﻿@typeparam TModel where TModel : class, new()

@inject IHttpService _httpService
@inject IQueryService _queryService
    @using OneOf;

<MDataTable Headers="Headers"
            Items="_items"
            FooterProps="props => { props.ItemsPerPageOptions = new List<OneOf<int, DataItemsPerPageOption>>() { 5,10, 20, 30 }; }"
            MustSort
             SortBy="@SortByItem"
             SortDesc="@SortDesc"
             OnOptionsUpdate="HandleOnOptionsUpdate"
             ServerItemsLength="_totalDesserts"
             Loading="_loading"
             Class="@Class"
             LoadingText="@LoadingText">
     <TopContent>
         <MToolbar Flat>
            <MToolbarTitle> @Title</MToolbarTitle>
            <MDivider Class="mx-4" Inset Vertical />
             <MSpacer></MSpacer>
             @ButtonContent
             @if (ShowAddButton)
            {
                <MButton Color="primary" Rounded="Rounded"
                          Dark
                          Class="me-8"
                          OnClick="OnClickAdd">
                     <MIcon Left>mdi-plus</MIcon>
                 添加
             </MButton>
            }

            <MTextField Value="_search" ValueChanged="OnSearch" TValue="string"
                        AppendIcon="mdi-magnify"
                        Label="搜索"
                            SingleLine
                         HideDetails="true"></MTextField>
         </MToolbar>

     </TopContent>
     <ItemColContent>
         @ItemColContent(context)
     </ItemColContent>
 </MDataTable>

 @code {
    [Parameter]
    public List<DataTableHeader<TModel>> Headers { get; set; }
    [Parameter]
    public string ApiUrl { get; set; }
    [Parameter]
    public string SortByItem { get; set; } = "Id";
    [Parameter]
    public bool SortDesc { get; set; } = true;
    [Parameter]
    public string Title { get; set; }
    [Parameter]
    public string LoadingText { get; set; }
    [Parameter]
    public bool ShowAddButton { get; set; } = true;
    [Parameter]
    public bool Rounded { get; set; } = true;
    [Parameter]
    public string Class { get; set; } = "elevation-1";
    [Parameter]
    public RenderFragment<ItemColProps<TModel>> ItemColContent { get; set; }
    [Parameter]
    public RenderFragment ButtonContent { get; set; }
    [Parameter]
    public EventCallback OnClickAdd { get; set; }
    [Parameter]
    public Expression<Func<TModel, bool>> Predicate { get; set; }
    [Parameter]
    public List<TModel> DataSource { get; set; }

    private int _totalDesserts = 0;
    private IEnumerable<TModel> _items = new List<TModel>();
    private bool _loading = true;
    public string _search;
    private QueryResultModel<TModel> Data = new QueryResultModel<TModel>();
    MDataTable<TModel> _dataTable;

    [CascadingParameter]
    public ErrorHandler ErrorHandler { get; set; }

    public void HandleOnOptionsUpdate(DataOptions options)
    {
        CopyOptions(Data.Parameter, options);
        GetDataFromApi();
    }

    protected override void OnInitialized()
    {
        //CopyOptions(_dataCache.Date.Parameter, new DataOptions());
        GetDataFromApi();
    }

    public void GetDataFromApi()
    {
        _loading = true;
        GetDataAsync().ContinueWith(task =>
        {
            var data = task.Result;
            _items = data.items;
            _totalDesserts = data.total;
            _loading = false;

            InvokeAsync(StateHasChanged);
        });
    }

    public void OnSearch(string text)
    {
        Data.Parameter.SearchText = text;
        StateHasChanged();
        GetDataFromApi();
    }

    public async Task<(IEnumerable<TModel> items, int total)> GetDataAsync()
    {
        if (string.IsNullOrWhiteSpace(ApiUrl))
        {
            return await _queryService.QueryAsync<TModel, string>(DataSource.AsQueryable(), Data.Parameter, Predicate == null ? s => true : Predicate);
        }
        else
        {
            try
            {
                Data = await _httpService.PostAsync<QueryParameterModel, QueryResultModel<TModel>>(ApiUrl, Data.Parameter);
                return (Data.Items, Data.Total);
            }
            catch (Exception ex)
            {
                await ErrorHandler.ProcessError(ex, $"获取 {Title} 数据失败");
                return (new List<TModel>(), 0);
            }
        }
    }

    public void CopyOptions(QueryParameterModel parameter, DataOptions options)
    {
        parameter.SortBy = options.SortBy;
        parameter.SortDesc = options.SortDesc;
        parameter.MultiSort = options.MultiSort;
        parameter.MustSort = options.MustSort;
        parameter.GroupBy = options.GroupBy;
        parameter.GroupDesc = options.GroupDesc;
        parameter.ItemsPerPage = options.ItemsPerPage == 0 ? 10 : options.ItemsPerPage;
        parameter.Page = options.Page == 0 ? 1 : options.Page;
    }
 }
